//全局对象配置

ybvm = {
    toolsFunc: {},//功能函数修改操作
    config: {},
    envFunc: {} //具体环境实现
}

ybvm.config.proxy = false
//浏览器具体实现


ybvm.envFunc.EventTarget_addEventListener = function EventTarget_addEventListener() {
    console.log(this);
    console.log(this === window);
    console.log(arguments);
    debugger
    return 6666
}




//插件相关的函数



!function () {

    //env环境分发器
    ybvm.toolsFunc.dispatch = function dispatch(self, obj, objeName, funcName, argList, defaultValue) {
        let name = `${objeName}_${funcName}`//EventTraget_addEventListener
        console.log(name);
        try {
            ybvm.envFunc[name].apply(self, argList)
        } catch (error) {
            if (defaultValue === undefined) {
                console.log(`${name}正在执行,错误信息${error.message}`);
            }
            return defaultValue
        }



    }

    // 重写 defineProperty 方法并且内部,对get set value 等于方法的时候进行保护
    ybvm.toolsFunc.defineProperty = function defineProperty(obj, proto, oldDescriptor) {
        let newDescriptor = {}
        newDescriptor.configurable = ybvm.config.proxy || oldDescriptor.configurable
        newDescriptor.enumerable = oldDescriptor.enumerable
        if (oldDescriptor.hasOwnProperty("writable")) {
            newDescriptor.writable = ybvm.config.proxy || oldDescriptor.writable
        }
        if (oldDescriptor.hasOwnProperty("value")) {
            let value = oldDescriptor.value
            if (typeof value === "function") {
                ybvm.toolsFunc.safeFunc(value, proto)

            }
            newDescriptor.value = value
        }
        if (oldDescriptor.hasOwnProperty("get")) {
            let get = oldDescriptor.get
            if (typeof get === "function") {
                ybvm.toolsFunc.safeFunc(get, `get ${proto}`)

            }
            newDescriptor.get = get
        }
        if (oldDescriptor.hasOwnProperty("set")) {
            let set = oldDescriptor.set
            if (typeof set === "function") {
                ybvm.toolsFunc.safeFunc(set, `set ${proto}`)
            }
            newDescriptor.set = set
        }

        Object.defineProperty(obj, proto, newDescriptor)
    }


    //函数native化
    !function () {
        // 保存原生的 Function.prototype.toString 方法
        const $toString = Function.prototype.toString
        // 创建一个 Symbol 对象，用于唯一标识自定义的 toString 方法
        const symbol = Symbol()
        // 定义一个新的 toString 方法，如果对象是函数类型，则返回自定义的字符串或原生的 toString 结果
        const toString = function () {
            return typeof this === "function" && (this[symbol] || $toString.call(this))
        }
        // 设置原生函数对象的属性，使其不可枚举但可配置可写，并赋予新的值
        function set_native(func, key, value) {
            Object.defineProperty(func, key, {
                enumerable: false,
                configurable: true,
                writable: true,
                value: value
            })
        }

        // 删除原生的 Function.prototype.toString 方法
        delete Function.prototype.toString
        // 将自定义的 toString 方法设置为 Function.prototype 的新 toString 方法
        set_native(Function.prototype, "toString", toString)
        // 使用 symbol 设置一个自定义的函数字符串表示形式
        set_native(Function.prototype.toString, symbol, "function toString() { [native code] }")
        // 在全局对象上添加一个 setNative 方法，用于设置函数对象的自定义 toString 方法
        ybvm.toolsFunc.setNative = function (func, functionName) {
            set_native(func, symbol, `function ${functionName || func.name || ""}() { [native code] }`)
        }
    }()


    //对象重命名
    ybvm.toolsFunc.reNameObj = function (obj, name) {
        Object.defineProperty(obj.prototype, Symbol.toStringTag, {
            value: name,
            writable: false,
            enumerable: false,
            configurable: true
        }
        )
    }
    //函数重命名
    ybvm.toolsFunc.reNameFun = function (fun, name) {
        // 定义对象fun的name属性
        Object.defineProperty(fun, "name", {
            value: name,
            writable: false,
            enumerable: false,
            configurable: true
        })
    }
    //方法重命名和原生化
    ybvm.toolsFunc.safeFunc = function safeFunc(fun, name) {
        ybvm.toolsFunc.setNative(fun, name)
        ybvm.toolsFunc.reNameFun(fun, name)
    }
    //对象重命名和原生化
    ybvm.toolsFunc.safeProto = function safeProto(obj, name) {
        ybvm.toolsFunc.setNative(obj, name)
        ybvm.toolsFunc.reNameObj(obj, name)
    }

    //atob的源码
    ybvm.toolsFunc.customAtob = function (base64) {
        if (typeof base64 !== 'string') {
            throw new Error('Input must be a string');
        }

        // Node.js 环境可直接用 Buffer
        if (typeof Buffer !== 'undefined') {
            return Buffer.from(base64, 'base64').toString('binary');
        }

        // 浏览器或兼容实现
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
        let output = '';
        let i = 0;

        // 移除非法字符（如换行符）
        base64 = base64.replace(/[^A-Za-z0-9+/=]/g, '');

        // Base64 解码核心逻辑
        while (i < base64.length) {
            const enc1 = chars.indexOf(base64[i++]);
            const enc2 = chars.indexOf(base64[i++]);
            const enc3 = chars.indexOf(base64[i++]);
            const enc4 = chars.indexOf(base64[i++]);

            const byte1 = (enc1 << 2) | (enc2 >> 4);
            const byte2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            const byte3 = ((enc3 & 3) << 6) | enc4;

            output += String.fromCharCode(byte1);
            if (enc3 !== 64) output += String.fromCharCode(byte2);
            if (enc4 !== 64) output += String.fromCharCode(byte3);
        }

        return output;
    }
    //btoa的源码
    ybvm.toolsFunc.customBtoa = function (str) {
        if (typeof str !== 'string') {
            throw new Error('Input must be a string');
        }

        // Node.js 环境可直接用 Buffer
        if (typeof Buffer !== 'undefined') {
            return Buffer.from(str, 'binary').toString('base64');
        }

        // 浏览器或兼容实现（仅处理 Latin1 字符）
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
        let output = '';
        let i = 0;

        // 将字符串转换为二进制字节（仅支持 0x00-0xFF）
        const bytes = new Uint8Array(str.length);
        for (let i = 0; i < str.length; i++) {
            bytes[i] = str.charCodeAt(i) & 0xFF; // 确保单字节
        }

        // Base64 编码核心逻辑
        while (i < bytes.length) {
            const byte1 = bytes[i++];
            const byte2 = bytes[i++];
            const byte3 = bytes[i++];

            const enc1 = byte1 >> 2;
            const enc2 = ((byte1 & 3) << 4) | (byte2 >> 4);
            const enc3 = ((byte2 & 15) << 2) | (byte3 >> 6);
            const enc4 = byte3 & 63;

            output += chars[enc1] + chars[enc2];
            output += typeof byte2 !== 'undefined' ? chars[enc3] : '=';
            output += typeof byte3 !== 'undefined' ? chars[enc4] : '=';
        }

        return output;
    }
    //抛出错误函数

    ybvm.toolsFunc.throwError = function throwError(name, message) {
        let e = new Error()
        e.name = name
        e.message = message
        e.stack = `${name}: ${message}`
        throw e
    }







}()



//env相关代码


EventTarget = function EventTarget() {
}

//保护原型链
ybvm.toolsFunc.safeProto(EventTarget, "EventTarget")

//添加属性
ybvm.toolsFunc.defineProperty(EventTarget.prototype, "addEventListener", {
    writable: true,
    enumerable: true,
    configurable: true,
    value: function () {


        return ybvm.toolsFunc.dispatch(this, EventTarget.prototype, "EventTarget", "addEventListener", arguments)


    }
})

//保护原型链







WindowProperties = function WindowProperties() {
}



//native 化
ybvm.toolsFunc.setNative(WindowProperties, "WindowProperties")


//修改实例对象名称
ybvm.toolsFunc.reNameObj(WindowProperties, "WindowProperties")

//删除构造器
delete WindowProperties.prototype.constructor


//设置原型链
Object.setPrototypeOf(WindowProperties.prototype, EventTarget.prototype)









Window = function Window() {
    ybvm.toolsFunc.throwError("TypeError", "Failed to construct 'Window': Illegal constructor")
}


//设置构造方法原型对象
Object.setPrototypeOf(Window.prototype, WindowProperties.prototype)

//保护原型
ybvm.toolsFunc.safeProto(Window, "Window")

// Window.prototype 原型链属性

ybvm.toolsFunc.defineProperty(Window.prototype, "TEMPORARY", { value: 0, writable: false, enumerable: true, configurable: false })
ybvm.toolsFunc.defineProperty(Window.prototype, "PERSISTENT", { value: 1, writable: false, enumerable: true, configurable: false })

//Window原型属性 
ybvm.toolsFunc.defineProperty(Window, "PERSISTENT", { value: 1, writable: false, enumerable: true, configurable: false })
ybvm.toolsFunc.defineProperty(Window, "TEMPORARY", { value: 0, writable: false, enumerable: true, configurable: false })









//小写window对象

//window不能用new Window 出来
window = {}

delete global
// delete Buffer
delete WindowProperties

//设置window原型链
Object.setPrototypeOf(window, Window.prototype)

ybvm.toolsFunc.defineProperty(window, "atob", {
    writable: true,
    enumerable: true,
    configurable: true,
    value: function atob(argu) {
        return ybvm.toolsFunc.customAtob(argu)
    }
}

)
ybvm.toolsFunc.defineProperty(window, "btoa", {
    writable: true,
    enumerable: true,
    configurable: true,
    value: function atob(argu) {
        return ybvm.toolsFunc.customBtoa(argu)
    }
}

)
ybvm.toolsFunc.defineProperty(window, "name", {
    enumerable: true,
    configurable: true,
    get: function () { },
    set: function () { }
}

)









//全局变量初始化
//用户初始化js
//需要代理的对象


// window = new Proxy(window, {})
//调试js
//异步js

